package edu.ua.cs.cs515.gcj.tetris;
import java.util.ArrayList;

/**
 * Manages information regarding a tetromino, including the color of the tetromino and
 * contains a list of all possible rotations.
 */
public class Tetromino {
	
	private char color;
	private int selection = 0;
	private ArrayList<int[][]> rotations = new ArrayList<int[][]>();
	
	private int[][] currentShape;
	private char type;
	
	private boolean collided = false;
	
	private int pivotY;
		
	// Depending on the type we generate a different tetromino
	public Tetromino(char type) {
		int[][] baseShape;
		if (type != 'I') {
			baseShape = new int[3][3];
		} else {
			baseShape = new int[4][4];
		}
		this.type = type;
		char uType = Character.toUpperCase(type);
		switch (uType) {
		case 'I':
			baseShape[0][1] = 1;
			baseShape[1][1] = 1;
			baseShape[2][1] = 1;
			baseShape[3][1] = 1;
			this.pivotY = 2;
			this.color = 'C';
			break;
		case 'J':
			baseShape[0][1] = 1;
			baseShape[1][1] = 1;
			baseShape[2][1] = 1;
			baseShape[2][0] = 1;
			this.color = 'B';
			break;
		case 'L':
			baseShape[0][1] = 1;
			baseShape[1][1] = 1;
			baseShape[2][1] = 1;
			baseShape[2][2] = 1;
			this.color = 'O';
			break;
		case 'O':
			baseShape[0][1] = 1;
			baseShape[0][2] = 1;
			baseShape[1][1] = 1;
			baseShape[1][2] = 1;
			this.color = 'Y';
			break;
		case 'S':
			baseShape[0][2] = 1;
			baseShape[0][1] = 1;
			baseShape[1][1] = 1;
			baseShape[1][0] = 1;
			this.color = 'G';
			break;
		case 'T':
			baseShape[1][0] = 1;
			baseShape[1][1] = 1;
			baseShape[1][2] = 1;
			baseShape[2][1] = 1;
			this.color = 'M';
			break;
		case 'Z':
			baseShape[1][0] = 1;
			baseShape[1][1] = 1;
			baseShape[2][1] = 1;
			baseShape[2][2] = 1;
			this.color = 'R';
			break;
		}
		rotations.add(baseShape.clone());
		for (int i=1;i<4;i++) {
			rotations.add(rotate(rotations.get(i-1)));
		}
		currentShape = rotations.get(selection);
	}
	
	public int getPivotY() {
		return this.pivotY;
	}
	
	// Returns the number of empty rows at the top of the tetromino
	public int getTopWhiteSpace() {
		int whiteSpace = 0;
		for (int row=0;row<currentShape.length;row++) {
			boolean found = true;
			for (int col=0;col<currentShape[row].length;col++) {
				if (currentShape[row][col] != 0) {
					found = false;
					break;
				}
			}
			if (found == true) {
				whiteSpace++;
			} else {
				break;
			}
		}
		return whiteSpace;
	}
	
	public int getLeftWhiteSpace() {
		int whiteSpace = 0;
		for (int col=0;col<currentShape[0].length;col++) {
			boolean found = true;
			for (int row=0;row<currentShape.length;row++) {
				if (currentShape[row][col] != 0) {
					found = false;
					break;
				}
			}
			if (found == true) {
				whiteSpace++;
			} else {
				break;
			}
		}
		return whiteSpace;
	}
	
	public int getMaxWidth() {
		int leftCol = -1;
		int rightCol = -1;
		for (int col=0;col<currentShape[0].length;col++) {
			for (int row=0;row<currentShape.length;row++) {
				if (currentShape[row][col] != 0) {
					leftCol=col;
					break;
				}
			}
			if (leftCol > -1) {
				break;
			}
		}
		for (int col=currentShape[0].length-1;col>-1;col--) {
			for (int row=0;row<currentShape.length;row++) {
				if (currentShape[row][col] != 0) {
					rightCol=col;
					break;
				}
			}
			if (rightCol > -1) {
				break;
			}
		}
		return rightCol-leftCol+1;
	}
	
	public int getMaxHeight() {
		int topRow = -1;
		int bottomRow = -1;
		for (int row=0;row<currentShape.length;row++) {
			for (int col=0;col<currentShape[row].length;col++) {
				if (currentShape[row][col] != 0) {
					topRow=row;
					break;
				}
			}
			if (topRow > -1) {
				break;
			}
		}
		for (int row=currentShape.length-1;row>-1;row--) {
			for (int col=0;col<currentShape[row].length;col++) {
				if (currentShape[row][col] != 0) {
					bottomRow=row;
					break;
				}
			}
			if (bottomRow > -1) {
				break;
			}
		}
		return bottomRow-topRow+1;
	}
	
	// Rotates the tetromino left by cycling left through the list of rotations
	public void rotateLeft() {
		if (selection == 0) {
			selection = 3;
		} else {
			selection--;
		}
		currentShape = rotations.get(selection);
	}
	
	// Gets the color of the tetromino
	public char getColor() {
		return this.color;
	}
	
	// Rotates the shape matrix parameter and returns the rotated matrix.
	private int[][] rotate(int[][] shape) {
		
		int[][] tempShape = new int[shape.length][shape[0].length];
		for (int i=0;i<tempShape.length;i++) {
			for (int j=0;j<tempShape[0].length;j++) {
				tempShape[i][j] = shape[j][i];
			}
		}
		int tmp;
		for (int k=0;k<tempShape.length;k++) {
			tmp = tempShape[k][2];
			tempShape[k][2] = tempShape[k][0];
			tempShape[k][0] = tmp;
		}
	    
	    return tempShape;

	}
	
	public int[][] getRotatedMatrix() {
		int sel;
		if (selection == 0) {
			sel = 3;
		} else {
			sel=selection-1;
		}
		return rotations.get(sel);
	}
	
	// Returns the matrix corresponding to this tetromino
	public int[][] getShapeMatrix() {
		return this.currentShape;
	}

}